package com.bensoft.minesweeper.gui;

import com.bensoft.minesweeper.ApplicationController;
import com.bensoft.minesweeper.gui.minesweeperframe.Grid;
import com.bensoft.minesweeper.gui.preferences.ApplicationPreferences;
import com.bensoft.minesweeper.resources.strings.StringResources;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 *
 * @author Ben Wolsieffer
 */
public class CustomGameDialog extends JDialog implements GUILoader {

    private JTextField mineBox, heightBox, widthBox;
    private JButton okButton, cancelButton;
    private JPanel fieldsAndLabelsPanel, buttonPanel;

    public CustomGameDialog() {
        init();
    }

    private void init() {
        initializeComponents();
        setLayouts();
        addComponents();
        addComponentListeners();
        otherInit();
    }

    @Override
    public void initializeComponents() {
        okButton = new JButton(StringResources.getString("gui.button.ok"));
        cancelButton = new JButton(StringResources.getString("gui.button.cancel"));

        heightBox = new JTextField(Integer.toString(ApplicationPreferences.getHeight()), 5);
        widthBox = new JTextField(Integer.toString(ApplicationPreferences.getWidth()), 5);
        mineBox = new JTextField(Integer.toString(ApplicationPreferences.getMines()), 5);

        fieldsAndLabelsPanel = new JPanel();
        buttonPanel = new JPanel();
    }

    @Override
    public void setLayouts() {
        setLayout(new BorderLayout());
        fieldsAndLabelsPanel.setLayout(new GridLayout(0, 2, 0, 5));
        buttonPanel.setLayout(new BorderLayout(0, 10));
    }

    @Override
    public void addComponents() {
        fieldsAndLabelsPanel.add(new JLabel(StringResources.getString("gui.dialog.customgame.label.height") + ":"));
        fieldsAndLabelsPanel.add(heightBox);
        fieldsAndLabelsPanel.add(new JLabel(StringResources.getString("gui.dialog.customgame.label.width") + ":"));
        fieldsAndLabelsPanel.add(widthBox);
        fieldsAndLabelsPanel.add(new JLabel(StringResources.getString("gui.dialog.customgame.label.mines") + ":"));
        fieldsAndLabelsPanel.add(mineBox);
        buttonPanel.add(okButton, BorderLayout.NORTH);
        buttonPanel.add(cancelButton, BorderLayout.SOUTH);
        add(fieldsAndLabelsPanel, BorderLayout.WEST);
        add(buttonPanel, BorderLayout.EAST);
    }

    @Override
    public void addComponentListeners() {
        okButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                int numMines = Integer.parseInt(mineBox.getText());
                int numWidth = Integer.parseInt(widthBox.getText());
                int numHeight = Integer.parseInt(heightBox.getText());

                // Check that the height is within the valid range
                if (numHeight < Grid.MIN_HEIGHT) {
                    numHeight = Grid.MIN_HEIGHT;
                }
                if (numWidth < Grid.MIN_WIDTH) {
                    numWidth = Grid.MIN_WIDTH;
                }

                // Check that the width is within the valid range
                if (numWidth > Grid.MAX_WIDTH) {
                    numWidth = Grid.MAX_WIDTH;
                }
                if (numHeight > Grid.MAX_HEIGHT) {
                    numHeight = Grid.MAX_HEIGHT;
                }

                // Check that the # of mines is within the valid range
                if (numMines < Grid.MIN_MINES) {
                    numMines = Grid.MIN_MINES;
                }
                if (numMines > Grid.MAX_MINES) {
                    numMines = Grid.MAX_MINES;
                }

                // Check if the number of mines is greater than the number of 
                // spaces, and if so make it so there is one empty space.
                if (numMines >= numWidth * numHeight) {
                    numMines = (numWidth * numHeight - 1);
                }

                // Changes the text fields to the valid values because the 
                // dialog is only hidden when it closed.

                // TODO Maybe dispose the dialog upon close and remove this code
                // to save memory.
                widthBox.setText(Integer.toString(numWidth));
                heightBox.setText(Integer.toString(numHeight));
                mineBox.setText(Integer.toString(numMines));

                // Sets the grid size with the new values
                ApplicationController.getGameManager().setGridSize(numWidth, numHeight, numMines);
                // Resets the game
                ApplicationController.getGameManager().resetGame();
            }
        });
        cancelButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
        });
    }

    @Override
    public void otherInit() {
        getRootPane().setBorder(BorderFactory.createEmptyBorder(30, 15, 30, 15));
        buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
        setResizable(false);

        setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        setTitle(StringResources.getString("gui.dialog.customgame.title"));
        pack();
        setModalityType(DEFAULT_MODALITY_TYPE);
    }

    @Override
    public void setVisible(boolean b) {
        setLocationRelativeTo(ApplicationController.getMinesweeperFrame());
        super.setVisible(b);
    }
}
